package com.nononsenseapps.feeder.ui.rule

import android.os.Bundle
import android.text.Spannable
import android.text.SpannableString
import android.text.style.TextAppearanceSpan
import android.view.*
import android.widget.CheckBox
import android.widget.ImageView
import android.widget.TextView
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatDelegate
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.paging.PagedList
import androidx.paging.PagedListAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.nononsenseapps.feeder.db.ARG
import com.nononsenseapps.feeder.db.entity.FEED_ITEM_RULE_SOURCE
import com.nononsenseapps.feeder.db.entity.FeedRule
import com.nononsenseapps.feeder.db.room.ID_ALL_FEEDS
import com.nononsenseapps.feeder.db.room.ID_UNSET
import com.nononsenseapps.feeder.glide.GlideImageLoader
import com.nononsenseapps.feeder.ui.R
import com.nononsenseapps.feeder.ui.base.CoroutineScopedActivity
import com.nononsenseapps.feeder.ui.common.DividerColor
import com.nononsenseapps.feeder.util.FeedExtensions.feedRuleSourceDictionary
import com.nononsenseapps.feeder.util.FeedExtensions.getRuleStyleString
import kotlinx.coroutines.CoroutineScope


class FeedRuleListActivity : CoroutineScopedActivity() {

    val feedRuleViewModel:FeedRuleViewModel by viewModels()
    private lateinit var feedRuleList: RecyclerView
    private lateinit var adapter: FeedRuleAdapter

    private var ruleFeedId = ID_ALL_FEEDS

    private val feedItemListObserver by lazy {
        Observer<PagedList<FeedRule>> {
            adapter.submitList(it)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        if (shouldBeFloatingWindow()) {
            setupFloatingWindow()
        }
        super.onCreate(savedInstanceState)
        setContentView(R.layout.fragment_rule)

        val i = intent
        if (i != null) {
            // Existing id
            ruleFeedId = i.getLongExtra(ARG.FEED_ID, ID_ALL_FEEDS)
        }

        // Not persisted so set nightmode every time we start
        AppCompatDelegate.setDefaultNightMode(settingsViewModel.themePreference)

        feedRuleList = findViewById(R.id.feed_rule_list)

        adapter= FeedRuleAdapter(object:FeedRuleCallBack{
            override fun getFeedName(feedId: Long): String {
               return globalViewModel.getFeedName(feedId)
            }

            override fun navigateToFeedRuleFragment(item: FeedRule) {
                navigateToFeedRuleFragment(item.id)
            }

            override fun updateFeedAble(id: Long, able: Boolean) {
                feedRuleViewModel.updateFeedAble(id, able)
            }

            override fun deleteFeedRule(id: Long) {
                feedRuleViewModel.deleteFeedRule(id)
            }

            override fun getScope(): CoroutineScope {
                return lifecycleScope
            }

        })
        feedRuleList.layoutManager=LinearLayoutManager(this)
        feedRuleList.adapter=adapter
        feedRuleList.addItemDecoration( DividerColor(this,  DividerColor.VERTICAL_LIST))
        
        bindViewModel()
    }

    private fun bindViewModel() {
        feedRuleViewModel.livePagedAll(ruleFeedId).observe(this,feedItemListObserver)
    }

    fun navigateToFeedRuleFragment(feedRuleId: Long = ID_UNSET){
       val dialog = FeedRuleEditorDialog()
        val bundle = Bundle()
        bundle.putLong(ARG.FEED_ITEM_RULE_ID,feedRuleId)
        dialog.arguments=bundle
        dialog.showNow(supportFragmentManager,"Feed Rule")
    }
}

class FeedRuleHolder(val v:View,val callBack: FeedRuleCallBack): RecyclerView.ViewHolder(v), View.OnClickListener ,View.OnCreateContextMenuListener{

    private val feedRuleImage: ImageView = v.findViewById(R.id.feed_rule_image)

    private val feedRuleSub: TextView = v.findViewById(R.id.feed_rule_sub)

    private val feedRuleSnippet: TextView = v.findViewById(R.id.feed_rule_snippet)

    private val feedRuleType : TextView = v.findViewById(R.id.feed_rule_type)

    private val feedRuleAble : CheckBox = v.findViewById(R.id.feed_rule_able)

    private val feedRuleStyle : TextView = v.findViewById(R.id.feed_rule_style)

    private var item : FeedRule? = null

    init {
        v.setOnClickListener(this)
        v.setOnCreateContextMenuListener(this)

        feedRuleAble.setOnClickListener {
            item?.let {
                callBack.updateFeedAble(it.id,feedRuleAble.isChecked)
            }
        }
    }

    override fun onClick(v: View?) {
        item?.let {
            callBack.navigateToFeedRuleFragment(it)
        }
    }

    fun setFeedRule(feedRule: FeedRule?) {
        item=feedRule
        feedRule?.let { it ->
            val temps = if (it.ruleValue.isEmpty())
                it.title
            else
                it.title + " \n.\t\t" +  it.ruleValue + "\u2026"

            val textSpan = SpannableString(temps)
            textSpan.setSpan(TextAppearanceSpan(v.context, R.style.TextAppearance_ListItem_Body),
                it.title.length, temps.length,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

           textSpan.setSpan(TextAppearanceSpan(v.context, R.style.TextAppearance_ListItem_Title),
                    0, it.title.length,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

           feedRuleSnippet.text=textSpan

            if(it.adClick && it.style == FEED_ITEM_RULE_SOURCE.IMAGE_URL) {
                feedRuleImage.visibility = View.VISIBLE
                GlideImageLoader.glide(v.context, it.ruleValue,true)
                    .centerCrop()
                    .into(feedRuleImage)
            }else
                feedRuleImage.visibility=View.GONE

            if(it.feedId!=null)
                feedRuleSub.text = callBack.getFeedName(it.feedId!!)
            else
                feedRuleSub.text =v.context.getString( R.string.all_feeds)

            feedRuleType.text= getRuleStyleString(v.context,it)

            feedRuleAble.isChecked=it.able

            feedRuleStyle.text = feedRuleSourceDictionary[it.style]?.let { it1 ->
                v.context.getString(
                    it1
                )
            }
        }
    }

    override fun onCreateContextMenu(
        menu: ContextMenu?,
        v: View?,
        menuInfo: ContextMenu.ContextMenuInfo?
    ) {
        v?.context?.let { context ->
            if (menu != null) {
                MenuInflater(context).inflate(R.menu.feed_rule, menu)
                menu.findItem(R.id.action_delete).setOnMenuItemClickListener {
                    item?.let {
                        callBack.deleteFeedRule(it.id)
                    }
                    true
                }

            }
        }
    }

}

interface FeedRuleCallBack{

   fun getFeedName(feedId:Long):String

   fun navigateToFeedRuleFragment(item: FeedRule)

   fun updateFeedAble(id: Long, able: Boolean)

   fun deleteFeedRule(id: Long)

   fun getScope(): CoroutineScope
}

class FeedRuleAdapter(val callBack: FeedRuleCallBack) : PagedListAdapter<FeedRule, RecyclerView.ViewHolder>( FeedRuleDiffer) {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return FeedRuleHolder(LayoutInflater.from(parent.context).inflate(R.layout.list_rule_item, parent, false), callBack = callBack)
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val item=getItem(position)
        holder as FeedRuleHolder
        holder.setFeedRule(item)
    }
}

object FeedRuleDiffer : DiffUtil.ItemCallback<FeedRule>() {
    override fun areItemsTheSame(oldItem: FeedRule, newItem: FeedRule): Boolean {
       return oldItem.id==newItem.id
    }

    override fun areContentsTheSame(oldItem: FeedRule, newItem: FeedRule): Boolean {
        return oldItem.feedId==newItem.feedId && newItem.able == oldItem.able && newItem.adClick==oldItem.adClick && newItem.style==newItem.style &&  newItem.title == oldItem.title && newItem.ruleValue == oldItem.ruleValue
    }

}
